home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Apple Macintosh Developer Technical Support
- **
- ** File: TPieObj.c
- ** Written by: Eric Soldan
- **
- ** Copyright © 1992-1993 Apple Computer, Inc.
- ** All rights reserved.
- */
-
- /* You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes. */
-
- /* See the files "=How to write your app" and "=Using TreeObj.c" for information
- ** on this function. */
-
- /* This file implements the messages for the pie object. Many of the messages
- ** can be handled by the rect object, as they deal with a rect structure. Only
- ** a few of them are pie-specific. */
-
- /* We have a custom hit-test handler here because there are additional sizing
- ** grabbers for the pie object. The other objects just have grabbers at the
- ** corners. A pie object also has grabber objects to adjust the "pie-slice". */
-
-
-
- /*****************************************************************************/
-
-
-
- #include "App.h" /* Get the application includes/typedefs, etc. */
- #include "App.protos.h" /* Get the prototypes for the application. */
-
- #ifndef __OSEVENTS__
- #include <OSEvents.h>
- #endif
-
- #ifndef __OSUTILS__
- #include <OSUtils.h>
- #endif
-
- #ifndef __QUICKDRAW__
- #include <Quickdraw.h>
- #endif
-
- #ifndef __STRING__
- #include <String.h>
- #endif
-
- #ifndef __TREEOBJ2__
- #include "TreeObj2.h"
- #endif
-
- #ifndef __UTILITIES__
- #include "Utilities.h"
- #endif
-
-
-
- static OSErr PieLayerProc(LayerObj theLayer, short message);
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment DrawObjects
- long TPieObj(TreeObjHndl hndl, short message, long data)
- {
- ClickInfo *click;
- Rect rct;
- TreeObjHndl hhndl;
- RgnHandle rgn, oldClip, newClip, accumRgn;
- short arcs, arcl, arcs2, arcl2, diff, i, angle, h, w;
- Point pt, where, curMouse;
- long flip, newSize;
- LayerObj pieLayer;
- EventRecord option;
- RGBColor rgb, rgb2;
- #if VH_VERSION
- char *cptr;
- #endif
-
- switch (message) {
- case INITMESSAGE:
- TRectObj(hndl, message, data);
- mDerefPie(hndl)->arcStart = 0;
- mDerefPie(hndl)->arcLength = 360;
- break;
-
- case FREEMESSAGE:
- case COPYMESSAGE:
- case UNDOMESSAGE:
- case CONVERTMESSAGE:
- case FREADMESSAGE:
- case FWRITEMESSAGE:
- case HREADMESSAGE:
- case HWRITEMESSAGE:
- case GETOBJRECTMESSAGE:
- case SECTOBJRECTMESSAGE:
- case KEYMESSAGE:
- case SETSELECTMESSAGE:
- case GETSELECTMESSAGE:
- case COMPAREMESSAGE:
- return(TRectObj(hndl, message, data));
- break;
-
- case GETBBOXMESSAGE:
- return(TLineObj(hndl, message, data));
- break;
-
- case HITTESTMESSAGE:
- click = (ClickInfo *)data;
- hhndl = (TreeObjHndl)TRectObj(hndl, message, data);
- /* We must call TRectObj::HITTESTMESSAGE to set some static
- ** variables that TRectObj::SELECTOBJMESSAGE uses. */
- if ((!hhndl) && (click->message == HITTESTGRABBER)) {
- if (mDerefRoot(GetRootHndl(hndl))->numSelected == 1) {
- if (mDerefPie(hndl)->selected) {
- rct = mDerefPie(hndl)->arc;
- where = click->localEvent.where;
- InsetRect(&rct, -4, -4);
- if (PtInRect(where, &rct)) {
- GetMouse(&curMouse);
- for (i = 0; i < 2; ++i) {
- pt = (i) ? mDerefPie(hndl)->arcEnd : mDerefPie(hndl)->arcBegin;
- rct.bottom = (rct.top = pt.v - 3) + 6;
- rct.right = (rct.left = pt.h - 3) + 6;
- if (PtInRect(where, &rct)) {
- click->localEvent.where = pt;
- click->offset.h = pt.h - curMouse.h;
- click->offset.v = pt.v - curMouse.v;
- click->oldFlip = 0;
- click->newFlip = 0;
- click->grabber = 5 + i;
- hhndl = hndl;
- break;
- }
- }
- }
- }
- }
- }
- return((long)hhndl);
- break;
-
- case GETRGNMESSAGE:
- rgn = NewRgn();
- accumRgn = (RgnHandle)data;
- if (accumRgn)
- if (GetHandleSize((Handle)accumRgn) > 10000)
- return((long)rgn);
- NewLayer(&pieLayer, nil, PieLayerProc, nil, 0, (long)hndl);
- if (pieLayer) {
- SetLayerWorld(pieLayer);
- TPieObj(hndl, DRAWMESSAGE, DRAWMASK);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- ResetLayerWorld(pieLayer);
- DisposeLayer(pieLayer);
- }
- if (accumRgn)
- UnionRgn(rgn, accumRgn, accumRgn);
- return((long)rgn);
- break;
-
- case SETOBJRECTMESSAGE:
- TRectObj(hndl, message, data);
- CalcPiePoints(hndl);
- break;
-
- case DRAWMESSAGE:
- rct = mDerefPie(hndl)->arc;
- h = mDerefCommon(hndl)->penHeight;
- w = mDerefCommon(hndl)->penWidth;
- PenSize(w, h);
- if (!EmptyRect(&rct)) {
- arcs = mDerefPie(hndl)->arcStart;
- arcl = mDerefPie(hndl)->arcLength;
- switch (data) {
- case DRAWOBJ:
- GetClip(oldClip = NewRgn());
- newClip = (RgnHandle)TOvalObj(hndl, GETRGNMESSAGE, 0);
- if (newClip)
- SetClip(newClip);
- if (gQDVersion)
- GetForeColor(&rgb);
- ForeColor(whiteColor);
- if (gQDVersion) {
- rgb2 = mDerefPie(hndl)->contentColor;
- RGBForeColor(&rgb2);
- }
- PaintArc(&rct, arcs, arcl);
- ForeColor(blackColor);
- if (gQDVersion) {
- rgb2 = mDerefPie(hndl)->borderColor;
- RGBForeColor(&rgb2);
- }
- FrameArc(&rct, arcs, arcl);
- pt = mDerefPie(hndl)->arcBegin;
- MoveTo(pt.h - (w / 2), pt.v - (w / 2));
- pt = mDerefPie(hndl)->center;
- LineTo(pt.h - (w / 2), pt.v - (w / 2));
- pt = mDerefPie(hndl)->arcEnd;
- LineTo(pt.h - (w / 2), pt.v - (w / 2));
- if (gQDVersion)
- RGBForeColor(&rgb);
- SetClip(oldClip);
- DisposeRgn(oldClip);
- if (newClip)
- DisposeRgn(newClip);
- break;
- case ERASEOBJ:
- EraseArc(&rct, arcs, arcl);
- break;
- case DRAWSELECT:
- if (mDerefPie(hndl)->selected) {
- TRectObj(hndl, message, data);
- for (i = 0; i < 2; ++i) {
- pt = (i) ? mDerefPie(hndl)->arcEnd : mDerefPie(hndl)->arcBegin;
- rct.bottom = (rct.top = pt.v - 3) + 6;
- rct.right = (rct.left = pt.h - 3) + 6;
- InvertRect(&rct);
- arcl = mDerefPie(hndl)->arcLength;
- if ((arcl == -360) || (!arcl) || (arcl == 360)) break;
- }
- }
- break;
- case DRAWGHOST:
- PenMode(patXor);
- FrameArc(&rct, arcs, arcl);
- break;
- case DRAWMASK:
- FillArc(&rct, arcs, arcl, (ConstPatternParam)&qd.black);
- FrameArc(&rct, arcs, arcl);
- pt = mDerefPie(hndl)->arcBegin;
- MoveTo(pt.h - (w / 2), pt.v - (w / 2));
- pt = mDerefPie(hndl)->center;
- LineTo(pt.h - (w / 2), pt.v - (w / 2));
- pt = mDerefPie(hndl)->arcEnd;
- LineTo(pt.h - (w / 2), pt.v - (w / 2));
- break;
- }
- }
- PenNormal();
- break;
-
- case PRINTMESSAGE:
- TPieObj(hndl, DRAWMESSAGE, DRAWOBJ);
- break;
-
- #if VH_VERSION
- case VHMESSAGE:
- cptr = ((VHFormatDataPtr)data)->data;
- ccatchr(cptr, 13, 2);
- ccat (cptr, "$10: TPieObj:");
- ccatchr(cptr, 13, 1);
- ccat (cptr, " $00: selected = ");
- ccatdec(cptr, mDerefPie(hndl)->selected);
- ccatchr(cptr, 13, 1);
- rct = mDerefPie(hndl)->arc;
- ccat (cptr, " $02: pie = (");
- ccatdec(cptr, rct.top);
- ccat (cptr, ",");
- ccatdec(cptr, rct.left);
- ccat (cptr, ",");
- ccatdec(cptr, rct.bottom);
- ccat (cptr, ",");
- ccatdec(cptr, rct.right);
- ccat (cptr, ")");
- ccatchr(cptr, 13, 1);
- ccat (cptr, " $0A: arcStart = ");
- ccatdec(cptr, mDerefPie(hndl)->arcStart);
- ccatchr(cptr, 13, 1);
- ccat (cptr, " $0C: arcLength = ");
- ccatdec(cptr, mDerefPie(hndl)->arcLength);
- ccatchr(cptr, 13, 1);
- ccat (cptr, " $0E: center = (");
- ccatdec(cptr, mDerefPie(hndl)->center.v);
- ccat (cptr, ",");
- ccatdec(cptr, mDerefPie(hndl)->center.h);
- ccat (cptr, ")");
- ccatchr(cptr, 13, 1);
- ccat (cptr, " $12: arcBegin = (");
- ccatdec(cptr, mDerefPie(hndl)->arcBegin.v);
- ccat (cptr, ",");
- ccatdec(cptr, mDerefPie(hndl)->arcBegin.h);
- ccat (cptr, ")");
- ccatchr(cptr, 13, 1);
- ccat (cptr, " $16: arcEnd = (");
- ccatdec(cptr, mDerefPie(hndl)->arcEnd.v);
- ccat (cptr, ",");
- ccatdec(cptr, mDerefPie(hndl)->arcEnd.h);
- ccat (cptr, ")");
- ccatchr(cptr, 13, 1);
- return(true);
- break;
- #endif
-
- case CLICKMESSAGE:
- TRectObj(hndl, message, data);
- click = (ClickInfo *)data;
- if (click->message == CLICKDRAG) {
- AddPt(click->offset, &mDerefPie(hndl)->center);
- AddPt(click->offset, &mDerefPie(hndl)->arcBegin);
- AddPt(click->offset, &mDerefPie(hndl)->arcEnd);
- }
- break;
-
- case SIZEMESSAGE:
- click = (ClickInfo *)data;
- if (click->grabber <= 4) {
- newSize = TRectObj(hndl, message, data);
- click = (ClickInfo *)data;
- flip = (click->oldFlip ^ click->newFlip);
- if (flip) {
- arcs = mDerefPie(hndl)->arcStart;
- arcl = mDerefPie(hndl)->arcLength;
- if (flip & VFLIPOBJ) {
- arcs -= (i = (arcs < 180) ? 0 : 180);
- arcs = 180 - arcs;
- arcl = -arcl;
- arcs += i;
- }
- if (flip & HFLIPOBJ) {
- arcs = 360 - arcs;
- arcl = -arcl;
- }
- mDerefPie(hndl)->arcStart = arcs;
- mDerefPie(hndl)->arcLength = arcl;
- }
- CalcPiePoints(hndl);
- return(newSize);
- }
-
- GetMouse(&curMouse);
- curMouse.h += click->offset.h;
- curMouse.v += click->offset.v;
- rct = mDerefPie(hndl)->arc;
-
- arcs = arcs2 = mDerefPie(hndl)->arcStart;
- arcl = arcl2 = mDerefPie(hndl)->arcLength;
-
- PtToAngle(&rct, curMouse, &angle);
-
- if (click->grabber == 6) { /* Handle 2nd grabber as reverse first grabber case. */
- click->grabber = 5;
- arcs += arcl;
- arcl = -arcl;
- while (arcs > 360) arcs -= 360;
- while (arcs < 0) arcs += 360;
- }
-
- diff = angle - arcs;
- arcs = angle;
- OSEventAvail(nullEvent, &option);
- if (!(option.modifiers & shiftKey)) {
- while (diff > 180) diff -= 360; /* Force 1 change to be less than 180. */
- while (diff < -180) diff += 360;
- arcl -= diff;
- while (arcl > 360) arcl -= 360;
- while (arcl < -360) arcl += 360;
- }
-
- if ((arcs != arcs2) || (arcl != arcl2)) {
- mDerefPie(hndl)->arcStart = arcs;
- mDerefPie(hndl)->arcLength = arcl;
- CalcPiePoints(hndl);
- return(true);
- }
- break;
-
- default:
- break;
- }
-
- return(noErr);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- #pragma segment DrawObjects
- OSErr CalcPiePoints(TreeObjHndl hndl)
- {
- OSErr err;
- Rect rct;
- short arcs, arcl, i, angle;
- RgnHandle rgn;
- Point pt;
- long ll;
- LayerObj pieLayer;
-
- err = NewLayer(&pieLayer, nil, PieLayerProc, nil, 0, (long)hndl);
- if (err) return(err);
-
- rct = mDerefPie(hndl)->arc;
- arcs = mDerefPie(hndl)->arcStart;
- arcl = mDerefPie(hndl)->arcLength;
-
- SetLayerWorld(pieLayer);
- rgn = NewRgn();
-
- EraseRect(&rct);
- FillArc(&rct, 90, 90, (ConstPatternParam)&qd.black);
-
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt = *(Point *)(&(*rgn)->rgnBBox);
- ll = PinRect(&rct, pt);
- pt = *(Point *)≪
- mDerefPie(hndl)->center = pt;
-
- for (i = 0; i < 2; ++i) {
- angle = (i) ? (arcs + arcl) : (arcs);
- while (angle < 0) angle += 360;
- while (angle >= 360) angle -= 360;
- EraseRect(&rct);
- if (angle < 90) {
- FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.v = (*rgn)->rgnBBox.top;
- EraseRect(&rct);
- FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.h = (*rgn)->rgnBBox.right;
- if (angle > 45)
- --pt.h;
- }
- if ((angle >= 90) && (angle < 180)) {
- FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.h = (*rgn)->rgnBBox.right;
- EraseRect(&rct);
- FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.v = (*rgn)->rgnBBox.bottom;
- if (angle < 135)
- --pt.h;
- else
- --pt.v;
- }
- if ((angle >= 180) && (angle < 270)) {
- FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.v = (*rgn)->rgnBBox.bottom;
- EraseRect(&rct);
- FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.h = (*rgn)->rgnBBox.left;
- if (angle < 225)
- --pt.v;
- }
- if (angle >= 270) {
- FillArc(&rct, angle, 90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.h = (*rgn)->rgnBBox.left;
- EraseRect(&rct);
- FillArc(&rct, angle, -90, (ConstPatternParam)&qd.black);
- if (gQDVersion)
- BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
- else
- BitMapToRegion(rgn, &(*pieLayer)->layerPort->portBits);
- pt.v = (*rgn)->rgnBBox.top;
- }
- ll = PinRect(&rct, pt);
- pt = *(Point *)≪
- (i) ? (mDerefPie(hndl)->arcEnd = pt) : (mDerefPie(hndl)->arcBegin = pt);
- }
-
- DisposeRgn(rgn);
- ResetLayerWorld(pieLayer);
- DisposeLayer(pieLayer);
- return(noErr);
- }
-
-
-
- /*****************************************************************************/
-
-
-
- static OSErr PieLayerProc(LayerObj theLayer, short message)
- {
- OSErr err;
- TreeObjHndl pie;
- Rect rct;
- CGrafPtr keepPort;
- GDHandle keepGDevice;
- GWorldPtr layerWorld;
-
- switch (message) {
- case kLayerInit:
- err = noErr;
- if (theLayer) {
- if (!(*theLayer)->layerPort) {
- pie = (TreeObjHndl)(*theLayer)->layerData;
- rct = mDerefPie(pie)->arc;
- GetGWorld(&keepPort, &keepGDevice); /* Keep the GWorld. */
- err = NewGWorld(&layerWorld, 1, &rct, nil, nil, 0);
- if (err == noErr) {
- (*theLayer)->layerOwnsPort = true;
- SetPort((*theLayer)->layerPort = (GrafPtr)layerWorld);
- SetOrigin(rct.left, rct.top);
- EraseRect(&rct);
- }
- SetGWorld(keepPort, keepGDevice); /* Restore the kept GWorld. */
- }
- }
- else err = paramErr;
- break;
-
- default:
- err = DefaultLayerProc(theLayer, message);
- /* Default behavior for everything else. */
- break;
- }
-
- return(err);
- }
-
-
-
-